import axios, { type InternalAxiosRequestConfig, type AxiosResponse } from "axios";
import qs from "qs";
import { useUserStoreHook } from "@/store/modules/user";
import { ResultEnum } from "@/enums/ResultEnum";
import { getAccessToken } from "@/utils/auth";
import router from "@/router";
import md5 from "md5";
// import { ElLoading } from "element-plus";
// 创建 axios 实例

const service = axios.create({
  baseURL: import.meta.env.VITE_BASE_URL,
  timeout: 50000,
  headers: { "Content-Type": "application/json;charset=utf-8" },
  paramsSerializer: (params) => qs.stringify(params),
});
// 构建签名字符串的工具函数
const buildWaitSignString = (
  url: string,
  params: any,
  timestamp: string,
  deviceId: string
): string => {
  let waitSignParam = url;
  // 添加问号
  waitSignParam += "?";

  // 处理参数
  if (params && Object.keys(params).length > 0) {
    // 按字母顺序排序键名
    const sortedKeys = Object.keys(params).sort((a, b) => a.localeCompare(b));
    const paramPairs = sortedKeys.map((key) => {
      const value = params[key];
      if (value === null || value === undefined) {
        return `${key}=`;
      }
      // 如果值是对象或数组，转换为JSON字符串
      if (typeof value === "object" && value !== null) {
        return `${key}=${JSON.stringify(value)}`;
      }
      return `${key}=${value}`;
    });
    waitSignParam += paramPairs.join("&");
  }

  // 添加时间戳和设备ID
  waitSignParam += "#" + timestamp + "#" + deviceId;

  console.log("待签名字符串:", waitSignParam);

  // 移除所有空白字符
  return waitSignParam.replace(/\s+/g, "");
};
// 请求拦截器
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    const accessToken = getAccessToken();
    // 如果 Authorization 设置为 no-auth，则不携带 Token，用于登录、刷新 Token 等接口
    const timestamp = Math.floor(Date.now() / 1000).toString(); // 时间戳（秒）
    const deviceId = "0eb7f2c5-c68a-4fe3-8d78-d8512e1262d2"; // 设备ID
    // const deviceId = localStorage.getItem("deviceId") || generateUUID();

    const clientVersion = "100"; // 客户端版本号

    // 获取请求路径（不包含查询参数）
    const url = config.url?.split("?")[0] || "";

    // 获取参数
    // const params = config.method?.toLowerCase() === "get" ? config.params : config.data;
    const params = config.method?.toLowerCase() === "get" ? config.params : qs.parse(config.data);
    console.log(params, "parararar");
    console.log(config.params, "config.params");
    console.log(buildWaitSignString(url, params, timestamp, deviceId));
    // 构建签名字符串
    const signStr = buildWaitSignString(url, params, timestamp, deviceId);
    // MD5加密签名
    const signature = md5(signStr);
    console.log("签名结果:", signature);

    // 添加安全验证请求头
    config.headers["Ranyu-Security-Request-Timestamp"] = timestamp;
    config.headers["Ranyu-Security-Device-Id"] = deviceId;
    config.headers["Ranyu-Security-Client-Version"] = clientVersion;
    config.headers["Ranyu-Security-SIGNATURE"] = signature;
    if (config.headers.Authorization !== "no-auth" && accessToken) {
      config.headers.Authorization = accessToken;
      // config.headers.Authorization = `Bearer ${accessToken}`;
    } else {
      delete config.headers.Authorization;
    }
    return config;
  },
  (error) => Promise.reject(error)
);

// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse) => {
    // 如果响应是二进制流，则直接返回，用于下载文件、Excel 导出等
    if (response.config.responseType === "blob") {
      return response;
    }

    const { code, data, msg } = response.data;

    if (code == ResultEnum.SUCCESS) {
      return data;
    }

    // ElMessage.error(msg || "系统出错");
    return Promise.reject(new Error(msg || "Error"));
  },
  async (error) => {
    // console.error("request error", error); // for debug
    // 非 2xx 状态码处理 401、403、500 等
    const { config, response } = error;
    if (response) {
      const { code, msg } = response.data;
      if (code === ResultEnum.ACCESS_TOKEN_INVALID) {
        // Token 过期，刷新 Token
        return handleTokenRefresh(config);
      } else if (code === ResultEnum.REFRESH_TOKEN_INVALID) {
        return Promise.reject(new Error(msg || "Error"));
      } else {
        // ElMessage.error(msg || "系统出错");
      }
    }
    return Promise.reject(error.message);
  }
);

export default service;

// 是否正在刷新标识，避免重复刷新
let isRefreshing = false;
// 因 Token 过期导致的请求等待队列
const waitingQueue: Array<() => void> = [];

// 刷新 Token 处理
async function handleTokenRefresh(config: InternalAxiosRequestConfig) {
  return new Promise((resolve) => {
    // 封装需要重试的请求
    const retryRequest = () => {
      config.headers.Authorization = getAccessToken();
      resolve(service(config));
    };

    waitingQueue.push(retryRequest);

    if (!isRefreshing) {
      isRefreshing = true;

      // 刷新 Token
      useUserStoreHook()
        .refreshToken()
        .then(() => {
          // 依次重试队列中所有请求, 重试后清空队列
          waitingQueue.forEach((callback) => callback());
          waitingQueue.length = 0;
        })
        .catch((error: any) => {
          console.log("handleTokenRefresh error", error);
          // 刷新 Token 失败，跳转登录页
          ElNotification({
            title: "提示",
            message: "您的会话已过期，请重新登录",
            type: "info",
          });
          useUserStoreHook()
            .clearUserData()
            .then(() => {
              router.push("/login");
            });
        })
        .finally(() => {
          isRefreshing = false;
        });
    }
  });
}
